package org.hepeng.fabric.contract.api;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author he peng
 * @date 2022/3/23
 */
public abstract class ChainCodeRegistry {

    private static final Map<String , Map<String , Set<ContractDefinition>>> CHAIN_CODE_MAP = new ConcurrentHashMap<>();

    public static synchronized void add(Class<?> cls) {

        Optional<ContractDefinition> optional = ContractResolver.resolve(cls);
        if (optional.isPresent()) {
            ContractDefinition contractDefinition = optional.get();
            String chainCodeName = contractDefinition.getChainCodeName();
            String contractName = contractDefinition.getName();

            if (! CHAIN_CODE_MAP.containsKey(chainCodeName)) {

                Set<ContractDefinition> contracts = new HashSet<>();
                contracts.add(contractDefinition);

                Map<String , Set<ContractDefinition>> contractMap = new HashMap<>();
                contractMap.put(contractName , contracts);

                CHAIN_CODE_MAP.put(chainCodeName , contractMap);
            } else {
                Map<String, Set<ContractDefinition>> contractMap = CHAIN_CODE_MAP.get(contractDefinition.getChainCodeName());
                Set<ContractDefinition> contracts = contractMap.get(contractName);
                contracts.add(contractDefinition);
                contractMap.put(contractName , contracts);
                CHAIN_CODE_MAP.put(chainCodeName , contractMap);
            }
        }
    }

    public static Set<String> getAllContractName(String chaincode) {

        Map<String, Set<ContractDefinition>> contracts = CHAIN_CODE_MAP.get(chaincode);
        return Objects.nonNull(contracts) ? contracts.keySet() : new HashSet<>();
    }

    public static Set<String> getAllChainCodeName() {
        return CHAIN_CODE_MAP.keySet();
    }

}
